package cn.compose.online.biz;

import cn.compose.online.base.RespCodes;
import cn.compose.online.base.Response;
import cn.compose.online.base.ResponseBuilder;
import cn.compose.online.constant.GroovyConstants;
import cn.compose.online.dao.CodeHistoryMapper;
import cn.compose.online.dao.UserTokenMapper;
import cn.compose.online.entity.CodeHistory;
import cn.compose.online.util.GroovyGenerateUtils;
import cn.compose.online.util.ParamsParseUtils;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.C;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class CodeBiz {


    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private CodeHistoryMapper codeHistoryMapper;

    public Response generateCode(String data) {
        Response response = new Response();
        try {
            JSONObject json = JSONUtil.parseObj(data);
            //变量
            String variable = json.get("variableInput").toString();
            List<String> params = ParamsParseUtils.getDef(variable);
            Map<String, String> paramsMap = ParamsParseUtils.getDefMap(variable);
            if (CollectionUtils.isEmpty(params) || paramsMap == null) {
                response.setCode(RespCodes.PARAM_ERROR);
                response.setMessage("变量解析错误！填写有误或变量重复！");
                return response;
            }
            //条件
            String groovyGenerateCode = GroovyGenerateUtils.groovyGenerate(variable, json, GroovyConstants.typeGenerate);
            if (StringUtils.isBlank(groovyGenerateCode)) {
                response.setCode(RespCodes.PARAM_ERROR);
                response.setMessage("条件解析错误！");
                return response;
            }

            //运行
            String groovyRunCode = GroovyGenerateUtils.groovyGenerate(variable, json, GroovyConstants.typeRun);

            //运行参数名
            String codeParamsName = GroovyGenerateUtils.getInputParamsName(variable);

            //运行参数值名
            String codeParam = GroovyGenerateUtils.getInputParams(variable);

            JSONObject result = JSONUtil.createObj();
            String historyId = UUID.randomUUID().toString();
            result.set("MLCodeText", groovyGenerateCode);
            result.set("MLCodeParamName", codeParamsName);
            result.set("MLCodeParam", codeParam);
            result.set("RUNCodeText", groovyRunCode);
            result.set("historyId", historyId);

            //将数据缓存到redis并设置6小时的过期时间
            json.set("result", result);
            String key = GroovyConstants.codeRedisKey + historyId;
            redisTemplate.opsForValue().set(key, json);
            redisTemplate.expire(key, getOverTime(), TimeUnit.SECONDS);
            return ResponseBuilder.ok(result, "生成代码成功！");
        } catch (Exception e) {
            log.error("参数解析错误", e);
        }
        response.setCode(RespCodes.PARAM_REQUIRED);
        return response;
    }


    public Response saveCode(String historyId) {
        Response response = new Response();
        try {
            String key = GroovyConstants.codeRedisKey + historyId;
            Object object = redisTemplate.opsForValue().get(key);
            JSONObject jsonObject = JSONUtil.parseObj(object);
            //将数据保存到数据库
            CodeHistory codeHistory=new CodeHistory();
            codeHistory.setHistoryId(historyId);
            JSONObject result = jsonObject.getJSONObject("result");
            codeHistory.setMlCode(result.getStr("MLCodeText"));
            codeHistory.setRunCode(result.getStr("RUNCodeText"));
            codeHistory.setInputData(jsonObject.toString());
            codeHistory.setCreateDate(new Date());
            codeHistory.setStatus(0);
            codeHistoryMapper.insert(codeHistory);
            return ResponseBuilder.ok(jsonObject, "保存成功！");
        } catch (Exception e) {
            log.error("保存代码生成记录异常！", e);
        }
        return response;
    }


    public Long getOverTime() {
        //默认6小时，异常时默认设置过期时间为6小时
        long time = 21600L;
        try {
            long now = System.currentTimeMillis();
            SimpleDateFormat sdfOne = new SimpleDateFormat("yyyy-MM-dd");
            long overTime = (now - (sdfOne.parse(sdfOne.format(now)).getTime())) / 1000;
            //当前时间  距离当天晚上23:59:59  秒数 也就是今天还剩多少秒
            Random random = new Random();
            int num = random.nextInt(60);
            //在凌晨60秒内过期完，防止缓存雪崩
            time = 24 * 60 * 60 - overTime + num;
            return time;
        } catch (Exception e) {
            log.error("过去当天剩余时间失败", e);
        }
        return time;
    }
}
